package com.xbongbong.workflow.service.strategy.data.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.TaskTypeEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.message.pojo.dto.ConsistencySyncRabbitMqDTO;
import com.xbongbong.pro.workflow.enums.WorkflowOperateEnum;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.UserAndDepTeamEntity;
import com.xbongbong.saas.domain.entity.WarehouseUserEntity;
import com.xbongbong.saas.domain.entity.ext.WarehouseEntityExt;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.WarehouseEnum;
import com.xbongbong.saas.model.PaasFormSubDataModel;
import com.xbongbong.saas.model.WarehouseModel;
import com.xbongbong.saas.model.WarehouseUserModel;
import com.xbongbong.saas.service.ConsistencySyncService;
import com.xbongbong.saas.service.WarehouseService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.workflow.domain.entity.WorkflowBackupDataEntity;
import com.xbongbong.workflow.model.WorkflowBackupDataModel;
import com.xbongbong.workflow.pojo.Data;
import com.xbongbong.workflow.pojo.WorkflowTransferPOJO;
import com.xbongbong.workflow.service.strategy.data.AbstractWorkflowDataStrategy;
import com.xbongbong.workflow.service.strategy.data.WorkflowDataProcessStrategy;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 *
 * @author 魏荣杰
 *
 */
@Service
@Slf4j
public class WorkflowWarehouseStrategy extends AbstractWorkflowDataStrategy implements WorkflowDataProcessStrategy {

    @Resource
    private WorkflowBackupDataModel workflowBackupDataModel;
    @Resource
    private WarehouseModel warehouseModel;
    @Resource
    private WarehouseUserModel warehouseUserModel;
    @Resource
    private ConsistencySyncService consistencySyncService;
    @Resource
    private PaasFormSubDataModel paasFormSubDataModel;
    @Resource
    private WarehouseService warehouseService;

    @Override
    public List<Integer> type() {
        return Collections.singletonList(XbbRefTypeEnum.WAREHOUSE.getCode());
    }

    @Override
    public void save(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        // 文件柜
        saveDataCabinetFile(workflowTransferPOJO);


        // api
        apiHook(workflowTransferPOJO);
        addLinkDataDynamic(workflowTransferPOJO);
        // log
        afterSaveLog(workflowTransferPOJO);
    }

    @Override
    public void update(WorkflowTransferPOJO workflowTransferPOJO, SaasNeedRedundantAttrPojo saasNeedRedundantAttrPojo) throws XbbException {
        // 文件柜
        saveDataCabinetFile(workflowTransferPOJO);

        String corpid = workflowTransferPOJO.getCorpid();
        Data pojoData = workflowTransferPOJO.getData();
        JSONObject data = pojoData.getData();
        Long dataId = pojoData.getId();

        WorkflowBackupDataEntity workflowBackupDataEntity = workflowBackupDataModel.getByKey(workflowTransferPOJO.getBackupDataId(), corpid);
        JSONObject oldData = workflowBackupDataEntity.getData();

        String warehouseName = FastJsonHelper.getStringFromFormData(data, WarehouseEnum.WAREHOUSE_NAME.getAttr());
        String oldWarehouseName = FastJsonHelper.getStringFromFormData(oldData, WarehouseEnum.WAREHOUSE_NAME.getAttr());
        if (!Objects.equals(warehouseName, oldWarehouseName)) {
            try {
                updateProductLinkWarehouseName(corpid, dataId, warehouseName);
            } catch (Exception e) {
                log.error("编辑仓库名称后更新产品的关联仓库字段", e);
            }
        }

        //仓库名称一致性同步
        try{
            if (!Objects.equals(oldWarehouseName, warehouseName)) {
                ConsistencySyncRabbitMqDTO consistencySyncRabbitMqDTO = new ConsistencySyncRabbitMqDTO(corpid, dataId, warehouseName);
                consistencySyncService.syncWarehouse(consistencySyncRabbitMqDTO);
            }
        }catch (Exception e){
            log.error("数据一致性同步", e);
        }

        // api
        apiHook(workflowTransferPOJO);
        // log
        afterUpdateLog(workflowTransferPOJO);
    }

    public void updateProductLinkWarehouseName(String corpid, Long dataId, String warehouseName) throws XbbException {
        warehouseService.updateProductLinkWarehouseName(corpid, dataId, warehouseName);
    }


    @Override
    public void updateBack(Long taskId, WorkflowTransferPOJO workflowTransferPOJO) throws XbbException {
        String corpid = workflowTransferPOJO.getCorpid();
        Long backupDataId = workflowTransferPOJO.getBackupDataId();
        Long dataId = workflowTransferPOJO.getData().getId();
        WorkflowBackupDataEntity workflowBackupDataEntity = workflowBackupDataModel.getByKey(backupDataId, corpid);
        if (Objects.nonNull(workflowBackupDataEntity)) {
            JSONObject data = workflowBackupDataEntity.getData();

            replenishAttrForBackupData(workflowTransferPOJO.getData().getData(), data);

            WarehouseEntityExt warehouseEntityExt = new WarehouseEntityExt();
            warehouseEntityExt.setId(dataId);
            warehouseEntityExt.setCorpid(corpid);
            warehouseEntityExt.setData(data);
            warehouseEntityExt.setSerialNo(data.getString(FieldTypeEnum.SERIALNO.getAlias()));
            warehouseEntityExt.setOwnerId(getOwnerId(data));
            warehouseEntityExt.setDepartmentId(data.getLong(FieldTypeEnum.DEPARTMENTID.getAlias()));

            List<WarehouseUserEntity> warehouseUserEntities = JSON.parseArray(data.getString(StringConstant.USER_TEAM), WarehouseUserEntity.class);

            FormDataUtil.removeSystemData(data);
            data.remove(StringConstant.USER_TEAM);
            if (Objects.equals(workflowTransferPOJO.getOperate(), WorkflowOperateEnum.UPDATE.getType())) {
                warehouseEntityExt.setFlowStatus(FlowStatusEnum.PASS.getType());
            }
            warehouseModel.update(warehouseEntityExt);
            // 回退被删掉的子表单
            updateBackSubForm(warehouseEntityExt, corpid, IndexTypeEnum.IDX_SAAS_WAREHOUSE_SUB);
            //回退被删掉的富文本
            updateBackRichText(taskId, workflowTransferPOJO);;
            // 团队处理
            saveUserTeam(warehouseUserEntities, corpid, warehouseEntityExt.getId());

        }
    }

    @Override
    public void approvalFailed(Long taskId, WorkflowTransferPOJO workflowTransferPOJO, Integer taskType) throws XbbException {
        try {
            String corpid = workflowTransferPOJO.getCorpid();
            Data workflowData = workflowTransferPOJO.getData();
            Long dataId = workflowData.getId();
            Long formId = workflowData.getFormId();
            Integer businessType = workflowData.getBusinessType();
            Integer saasMark = workflowData.getSaasMark();
            WarehouseEntityExt warehouseEntityExt = new WarehouseEntityExt();
            warehouseEntityExt.setId(dataId);
            if (Objects.equals(TaskTypeEnum.REVOKE.getType(), taskType)) {
                warehouseEntityExt.setFlowStatus(FlowStatusEnum.REVOKE.getType());
            } else {
                warehouseEntityExt.setFlowStatus(FlowStatusEnum.REJECT.getType());
            }
            warehouseEntityExt.setCorpid(corpid);
            warehouseEntityExt.setUpdateTime(DateTimeUtil.getInt());
            warehouseModel.update(warehouseEntityExt);
            // 子表单
            DelEnum del = DelEnum.APPROVE_FAILED;
            paasFormSubDataModel.deleteBatchByDataId(Collections.singletonList(dataId), corpid, IndexTypeEnum.IDX_SAAS_WAREHOUSE_SUB, del);
            //富文本
            deleteFormRichText(dataId, corpid, formId, businessType, saasMark, DelEnum.NORMAL);
            // 团队
            List<WarehouseUserEntity> userEntities = warehouseUserModel.getUserListByDataId(corpid, dataId);
            if (CollectionUtils.isNotEmpty(userEntities)) {
                List<Long> delIds = new ArrayList<>();
                userEntities.forEach(item->delIds.add(item.getId()));
                warehouseUserModel.deleteBatchByIds(corpid, delIds, del.getDel());
            }
        } catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowWarehouseStrategy.approvalFailed error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    private void saveUserTeam(List<WarehouseUserEntity> warehouseUserEntities, String corpid, Long id) throws XbbException {
        try {

            List<Long> ids = new ArrayList<>();
            warehouseUserEntities.forEach(v -> ids.add(v.getId()));

            List<WarehouseUserEntity> userEntities = warehouseUserModel.getUserListByDataId(corpid, id);
            List<Long> delIds = userEntities.stream().filter(v -> !ids.contains(v.getId())).map(UserAndDepTeamEntity::getId).collect(Collectors.toList());

            warehouseUserModel.deleteBatchByIds(corpid, delIds, DelEnum.DELETE.getDel());

            warehouseUserModel.updateBatch(warehouseUserEntities, corpid);


        } catch (Exception e) {
            log.error("com.xbongbong.workflow.service.strategy.data.impl.WorkflowWarehouseStrategy.saveUserTeam error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }
}
